/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package br.siagefi.service;


import br.siagefi.dao.DAO;
import br.siagefi.model.Documento;
import br.siagefi.model.Lancamento;
import br.siagefi.model.Pessoa;
import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

/**
 *
 * @author NOTE
 */
public class DocumentoService {
    
    private final DAO<Documento> dao;
    private final LancamentoService lctoService;
    private final DataService dataService;
    private final ContaBancariaService contaService;
    

    public DocumentoService() {
        this.dao = new DAO<>(Documento.class);
        lctoService = new LancamentoService();
        dataService = new DataService();
        contaService = new ContaBancariaService();
    }
    
    public void inserir(Documento documento){
        dao.adiciona(documento);
    }
    
    public void alterar(Documento documento){
        dao.atualiza(documento);
    }
    
    public List<Documento> listar(){
        return dao.listaTodos();
    }
    
    public void remover(Documento documento){
        this.removerLancamentos(documento);
        dao.remove(documento);
    }
    
    public boolean removerLancamentos(Documento doc){
        if(!doc.getLancamentos().isEmpty()){
            for (Lancamento lancamento : doc.getLancamentos()) {
            lctoService.remover(lancamento);
            }
            doc.setLancamentos(new ArrayList<Lancamento>());
            return true;
        }else {
            return false;
        }
    }
    
    public void gravarDocumento(Documento doc) {
        this.inserir(doc);
        if(!doc.getLancamentos().isEmpty())
            for (Lancamento lancamento : doc.getLancamentos()) {
                lctoService.inserir(lancamento);
            }
    }
    
    public boolean jaExiste(Documento documento) {
        List<Documento> lista = this.listar();
        for (Documento d : lista) 
            if(d.equals(documento))
                return true;
        return false;
    }
    
    public void incluirLancamento (Documento doc){
        Lancamento lancamento;
        if(!doc.getLancamentos().isEmpty()){
            this.removerLancamentos(doc);
        }
        String situacao = this.obterSituacao(doc.getDataEmissao());
        if (doc.getFormaPagamento().equals("A_VISTA")){ 
            doc.setSituacao(situacao);
            lancamento = new Lancamento(1, doc.getDataEmissao(), doc.getValor(), doc.getNatureza(), situacao, doc.getConta(), doc);
            doc.getLancamentos().add(lancamento);
        } else {
            doc.setSituacao("A VENCER");
            if(doc.getValorEntrada() > 0){
                lancamento = new Lancamento(0, doc.getDataEmissao(), doc.getValorEntrada(), doc.getNatureza(), situacao, doc.getConta(), doc);
                doc.getLancamentos().add(lancamento);
            }
            double valorParcela = (doc.getValor() - doc.getValorEntrada()) / doc.getQtdeParcelas();
            Date dataParcela, data;
            data = doc.getDataPrimeiraParcela() != null ? doc.getDataPrimeiraParcela() : doc.getDataEmissao();
            for (int i = 0; i < doc.getQtdeParcelas(); i++) {
                dataParcela = dataService.getDataParcela(i+1, data, doc.getPeriodicidade());
                situacao = this.obterSituacao(dataParcela);
                lancamento = new Lancamento(i+1, dataParcela, valorParcela, doc.getNatureza(), situacao, doc.getConta(), doc);
                doc.getLancamentos().add(lancamento);
            }
        }
    }
    
    public String obterSituacao(Date data) {
        String situacao;
        GregorianCalendar date = new GregorianCalendar();
        date.setTime(data);
        if(new GregorianCalendar().getInstance().compareTo(date) < 0){
            situacao = "A VENCER";
        }else{
            situacao = "PAGO";
        }
        return situacao;
    }
        
    public boolean existeLancamentoVinculado(Documento documento) {
         return !documento.getLancamentos().isEmpty();
    }
    
    public List<Pessoa> listarNomesOrigem(String origem) {
        List<Pessoa> lista;
        if(origem == null){
            return null;
        }else{
            if (origem.equals("FORNECEDOR_PF")){
                 lista = new ArrayList(new FornecedorPFService().listar());
                 return lista;
            }
            if (origem.equals("FORNECEDOR_PJ")){
                 lista = new ArrayList(new FornecedorPJService().listar());
                 return lista;
            }
            if (origem.equals("CLIENTE_PF")){
                 lista = new ArrayList(new ClientePFService().listar());
                 return lista;
            }
            if (origem.equals("CLIENTE_PJ")){
                 lista = new ArrayList(new ClientePJService().listar());
                 return lista;
            }
            if (origem.equals("FUNCIONARIO")){
                 lista = new ArrayList(new FuncionarioService().listar());
                 return lista;
            }
            return null;
        }
    }

    public void atualizaSaldo(Documento documento) {
        contaService.atualizaSaldo(documento);
    }
    
    public void reverterLancamentos(Documento documento){
        for (Lancamento lcto : documento.getLancamentos()) {
            if(documento.getNatureza().equals("DEBITO")){
                lcto.setTipo("CREDITO");
            } else{
                lcto.setTipo("DEBITO");
            }
        }
        this.atualizaSaldo(documento);
    }

    public boolean validaValorLancamentos(Documento documento) {
        double valor = 0;
        for (Lancamento lcto : documento.getLancamentos()) 
            valor += lcto.getValor();
        if(valor != documento.getValor())
            return false;
        return true;
    }
    
    public void atualizaSituacaoDocumento(Documento documento) {
        String situacao = "PAGO";
        for (Lancamento lcto : documento.getLancamentos()) 
            if(lcto.getSituacao().equals("A VENCER"))
                situacao = lcto.getSituacao();
        documento.setSituacao(situacao);
    }
    
}
